Repository navigation
MAINT: Update npm dependencies - #326
Merged
Merged
Conversation
Bump all dependencies to the latest release within their current major version (Next.js 14.2.35, Chakra UI 2.10.10, ESLint 9.39.5, TypeScript 5.9.3, Playwright 1.64.1, webpack 5.112.2, etc.) and pin TypeScript to ^5 instead of the open-ended >=5.7.3 range.
date-fns v4 adds first-class time zone support; the only breaking changes concern TypeScript types and internal module layout. The formatDistanceToNow API used in src/lib/date-formatting.js is unchanged, and date-fns-tz 3.2 supports date-fns ^4.
feed v6 validates item ids as URLs when rendering Atom (Atom <id> must be an IRI), so the bare post slug threw 'Invalid URL' and atom.xml was silently not written. Use the post URL as the item id, and await generateRssFeed in getStaticProps so feed errors fail the build instead of being swallowed as an unhandled rejection.
The only breaking changes in glob 12/13 affect the CLI (unsafe --shell removed, CLI moved to glob-bin); the glob.sync API used in src/lib/posts.js is unchanged.
v3 stops writing to global.DOMPurify and adds named exports; switch
src/lib/sanitize-html.js to the named 'sanitize' export.
Pinned to ~3.19.0 rather than v4: 3.20+ / 4.x pull in jsdom 30, whose
undici dependency crashes on Node 20 ('Cannot read properties of
undefined (reading bind)') and requires Node ^22.22.2 || ^24.15.0.
The deploy workflow still builds on Node 20, so v4 is held back until
CI moves to a newer Node.
KaTeX 0.18 prefixes all internal CSS classes, so the stylesheet imported from katex/dist must match the KaTeX version that renders the math. rehype-katex 7 still declares katex ^0.16, so add an npm override forcing it (and micromark-extension-math) onto the top-level katex version. Its renderToString API is unchanged. Other breaking changes (strict-mode reporting of missing metrics in 0.19, internal __defineFunction API in 0.17) do not affect this site.
v3 is a rewrite in TypeScript published as ESM-only; the default export and the initialize()/send() API used in layout.js are unchanged.
v16 upgrades its refractor dependency to v5 (security fixes). The Prism component and the dist/cjs/styles/prism import path used in src/components/mdx/code.js are unchanged; verified Python code still tokenises and renders with the nord theme.
react-apexcharts 2 requires apexcharts >=5.10.1, so they are upgraded together. Neither package is currently imported anywhere in the site, so no code changes are needed.
v6 adds blockJS/blockDangerousJS serialize options, both defaulting to
true, which strips every JS expression from MDX. That silently dropped
the style={{...}} attribute in the parcels-v4 post. Posts are authored
in this repository, so pass blockJS: false to keep expressions while
leaving blockDangerousJS enabled.
Breaking changes since v11 (gesture callbacks receiving the target element in v12, removal of the optional @emotion/is-prop-valid dependency in v13, removal of internal compatibility APIs in v14) do not affect the motion.div used on the blog index or Chakra UI v2's internal transitions. Smoke-tested all pages, colour-mode toggle and the mobile navigation in a headless browser.
Upgrade next, @next/mdx and eslint-config-next to 16.4.3 and migrate: - next lint was removed in Next.js 16: replace .eslintrc with a flat eslint.config.mjs based on eslint-config-next/core-web-vitals and run the ESLint CLI directly. (next lint had already been broken with ESLint 9.) Fix the two errors it now reports: hooks called inside a map callback in desktop-nav.js, and an unescaped apostrophe in utrechtteam.js. - Turbopack is now the default bundler and only accepts serializable loader options, so reference rehype-slug by name in the @next/mdx config. - images.domains is deprecated; use images.remotePatterns. - Turbopack emits a per-page directory under .next/server/pages, so the waddendrifters.html page's chunk directory collided with the exported waddendrifters.html of the /waddendrifters page (EISDIR). Remove the duplicate waddendrifters.html page: on GitHub Pages a request for /waddendrifters.html is already served by the waddendrifters.html redirect page exported from /waddendrifters. - Accept the tsconfig.json and next-env.d.ts changes written by next build (jsx: react-jsx, generated route type imports).
Upgrade react, react-dom and @types/react to 19. Next.js 16 deprecates React 18 support for the Pages Router. The site does not use any of the APIs removed in React 19 (propTypes/defaultProps on function components, string refs, legacy context, ReactDOM.render, the global JSX namespace); forwardRef in mdx/link.js is still supported. Chakra UI v2 runs on React 19 without console errors (checked with a headless-browser smoke test of every page).
ESLint 10 drops eslintrc support entirely (already migrated to flat config with the Next.js 16 upgrade) and no longer honours /* eslint-env */ comments (none in this repo). eslint-config-next 16.4+ supports ESLint 10. Note: eslint-plugin-react, eslint-plugin-import and eslint-plugin-jsx-a11y (pulled in by eslint-config-next) have not yet widened their eslint peer range beyond ^9, so npm prints ERESOLVE peer warnings. npm ci still succeeds and the plugins' rules run correctly under ESLint 10.
TypeScript 6 deprecates target ES5 (a hard error in next build's type
check), so raise tsconfig's target to ES2017, the Next.js default.
The target only affects type checking here since Next.js compiles
with SWC.
TypeScript 7 (7.0.2) is held back: its package no longer exposes the
JavaScript compiler API, and typescript-eslint (used by
eslint-config-next) refuses to load with it ('typescript-eslint does
not support TS 7.0'; peer range is <6.1.0).
Chakra UI v3 is a rewrite with a new theming system and compound
component APIs. Migration (codemod-assisted via @chakra-ui/codemod,
then reviewed and finished by hand):
Packages
- @chakra-ui/react 2 -> 3. Remove @chakra-ui/icons, @chakra-ui/next-js
and @chakra-ui/system (no v3 equivalents; next-js was unused) and
@emotion/styled (no longer needed). Icons now come from react-icons
(Lucide set). Add next-themes for colour mode.
Theme and providers
- Replace extendTheme with createSystem/defineConfig in src/theme.js.
To keep the site looking as before, restore v2's container sizes
(container.lg etc.), responsive heading scale, inline links that
inherit text colour, 1rem container padding, dark background
(gray.800) and border colours.
- Add the official v3 snippets in src/components/ui (provider,
color-mode, tooltip). _app uses <Provider>; ColorModeScript is
replaced by next-themes (suppressHydrationWarning on <Html>).
Components
- useColorModeValue/useColorMode-based styling replaced by _dark
conditions so the static export renders correctly before hydration;
ColorModeImage renders both images and toggles them with CSS; the
colour-mode toggle is wrapped in ClientOnly.
- Compound components: Accordion, Alert, Avatar (new AuthorAvatar
helper), Card, Collapsible, Separator (was Divider), StackSeparator,
Tooltip snippet; hover Popover -> HoverCard in the desktop nav.
- Prop renames: spacing -> gap, colorScheme -> colorPalette,
noOfLines -> lineClamp, isOpen -> open, defaultIsOpen -> defaultOpen,
icon/leftIcon -> children, as={Link} -> asChild, isExternal removed
(custom Link already sets target/rel for external URLs),
useClipboard({ value }) returns { copied, copy }.
- MDX lists get explicit list-style types (v3's preflight removes them).
- Drop the unused SocialButton from the footer.
for more information, see https://pre-commit.ci
erikvansebille
approved these changes
Oct 28, 2026
erikvansebille
left a comment
Member
There was a problem hiding this comment.
Looks good indeed - happy to be merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I have gone through all the code here, and think that it looks good. I have also done inspections of the website.
This change sticks close to the original site design (I did try a version with the v4 Chakra UI defaults, but I think this version looks better)
Note
This PR (code changes and this description) was generated by an LLM (Claude Opus 5.5). Please review with that in mind, especially the Chakra UI v3 migration.
Updates every npm dependency to its latest version, except two that are held back (see below), and migrates the code to match. Each upgrade is its own commit, so the PR is easiest to review commit by commit.
Version bumps
Major
next,@next/mdxeslint-config-nextreact,react-dom@types/react@chakra-ui/reacteslinttypescript>=5.7.3^6.0.3date-fnsfeedglobkatexframer-motionnext-mdx-remotereact-ga4react-syntax-highlighterapexcharts/react-apexchartsisomorphic-dompurifyMinor/patch
@emotion/react,@fontsource-variable/inter,@mdx-js/loader,@mdx-js/react,react-icons,swr,playwright,webpack.Added / removed
next-themes(used by Chakra v3 for colour mode), plus an npmoverridesentry pinningkatex(see below).@chakra-ui/icons,@chakra-ui/next-js,@chakra-ui/system,@emotion/styled. Chakra v3 no longer uses them, or they were unused.Code and config changes
Next.js 16
next.config.mjs:images.domains→images.remotePatterns.rehype-slugis now referenced by package name, because Turbopack (now the default bundler) requires serializable loader options.next lintwas removed, so thelintscript is noweslint ., and.eslintrcis replaced by a flateslint.config.mjs.tsconfig.jsonandnext-env.d.ts.src/pages/waddendrifters.html.tsx. Under Turbopack its output collided with the exportedwaddendrifters.html, and the build failed (EISDIR). The static export still emitswaddendrifters.htmlfromsrc/pages/waddendrifters.tsx(same redirect to/blog/waddendrifters), so/waddendrifters.htmlkeeps working on GitHub Pages.Chakra UI v3
@chakra-ui/codemod, then finished every file by hand.createSystem. It carries over the v2 container sizes and padding, heading scale, inline link style, dark background and border colours.src/components/ui/._darkCSS conditions, so the static HTML is correct before React hydrates.AuthorAvatarhelper), Card, Collapsible, Separator and HoverCard use the v3 component structure. Renamed props are updated.SocialButtonin the footer.feed v6
Invalid URL, soatom.xmlwas silently not being written while the build still reported success. Items now use the post URL as their id.generateRssFeedis now awaited, so a feed error fails the build instead of being swallowed.next-mdx-remote v6
style={{...}}in the Parcels v4 post. SetblockJS: falseand keptblockDangerousJSon.katex 0.19
overridesentry ("katex": "$katex") makesrehype-katexrender with the same KaTeX version as the imported stylesheet.isomorphic-dompurify
sanitizeexport.TypeScript 6
tsconfig.jsontarget moves fromES5(now a hard error) toES2017.Lint fixes
Linting was already broken on
main:next lintcrashed on ESLint 9. Now that it runs, it found two errors, both fixed:.map()indesktop-nav.js;utrechtteam.js.No code changes needed
React 19, date-fns 4, glob 13, react-ga4 3, react-syntax-highlighter 16, framer-motion 14.
Held back
isomorphic-dompurifystays at~3.19.0, not 4.x. Versions 3.20 and up need Node ≥22.22.2 or ≥24.15, and the deploy workflow builds on Node 20, so they crash the build there. It can be bumped once CI moves to a newer Node.typescriptstays at 6.x, not 7. typescript-eslint (viaeslint-config-next) refuses to load with TS 7 and only supports versions below 6.1.Known caveats
eslint-plugin-react,-importand-jsx-a11ystill declare support only up to ESLint 9.npm cisucceeds and the rules still run.apexcharts,react-apexchartsandd3aren't imported anywhere and could be removed in a follow-up.Testing
npm run buildpasses on Node 24, and on Node 20 after every step.npm run lintis clean.npm ciworks from the lockfile, andnpm auditreports 0 vulnerabilities./cards/[id]page renders.🤖 Generated with Claude Code